package com.ilink.groundservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ilink.groundservice.entity.PO.dataset.DatasetMetadata;
import com.ilink.groundservice.entity.PO.langflowApp.Download;
import com.ilink.groundservice.entity.PO.langflowApp.Folder;
import com.ilink.groundservice.entity.PO.langflowApp.Like;
import com.ilink.groundservice.entity.PO.langflowApp.StoreFlow;
import com.ilink.groundservice.entity.PO.langflowApp.Tag;
import com.ilink.groundservice.entity.PO.langflowApp.UserChatFlow;
import com.ilink.groundservice.entity.PO.model.ModelLangflow;
import com.ilink.groundservice.entity.VO.langflowApp.*;
import com.ilink.groundservice.mapper.langflowApp.*;
import com.ilink.groundservice.mapper.model.ModelLangflowMapper;
import com.ilink.groundservice.service.LangflowAppService;
import com.ilink.ilinkcommon.utils.SnowflakeIdGenerator;
import com.ilink.ilinkcommon.utils.UserContext;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <h3>new-ilink-java-backend</h3>
 *
 * @Description <p>langflow应用广场service实现</p>
 * @Author 30955
 * @Date 2024-09-19 18:29
 **/

@Service
@Transactional
@RequiredArgsConstructor
public class LangflowAppServiceImpl implements LangflowAppService {

    private final StoreFlowMapper storeFlowMapper;

    private final StoreFlowTagMapper storeFlowTagMapper;

    private final UserChatFlowMapper userChatFlowMapper;
    
    private final ModelLangflowMapper modelLangflowMapper;


    private final TagMapper tagMapper;

    private final LikeMapper likeMapper;

    private final DownloadMapper downloadMapper;

    private final FolderMapper folderMapper;
    private final UserApiKeysMapper userApiKeysMapper;

    @Override
    public CheckStoreResult check(){
        return new CheckStoreResult(true);
    }

    @Override
    public UploadFlowResult uploadFlow(UploadFlowInfo flowInfo) {
        flowInfo.selfGenerateMetaData();
        storeFlowMapper.insert(flowInfo);
        for (String tagId : flowInfo.getTags()) {
            storeFlowTagMapper.insertStoreFlowTag(flowInfo.getFlowId(), tagId);

        }
        return new UploadFlowResult(flowInfo.getFlowId());
    }

    @Override
    public UpdateFlowResult updateFlow(UploadFlowInfo flowInfo) {
        flowInfo.selfGenerateMetaData();
        storeFlowMapper.updateById(flowInfo);
        HashSet<String> oldTags =new HashSet<>(storeFlowTagMapper.getTagIdsByFlowId(flowInfo.getFlowId()));
        HashSet<String> newTags = new HashSet<>(flowInfo.getTags());
        HashSet<String> backup = new HashSet<>(newTags);
        newTags.removeAll(oldTags);
        oldTags.removeAll(backup);
        for (String tagId : newTags) {
            storeFlowTagMapper.insertStoreFlowTag(flowInfo.getFlowId(), tagId);
        }
        for (String tagId : oldTags) {
            storeFlowTagMapper.deleteStoreFlowTag(flowInfo.getFlowId(), tagId);
        }
        return new UpdateFlowResult(flowInfo.getFlowId());
    }

    @Override
    public GetFlowsByConditionResult getFlowsByCondition(QueryConditionInfo condition) {
        // 使用MyBatis Plus分页
        Page<StoreFlowInfo> page = new Page<>(condition.getPage(), condition.getLimit());

        // 根据条件查询流程信息，并进行分页
        IPage<StoreFlowInfo> pageInfo = storeFlowMapper.getFlowInfosByCondition(page, condition);
        List<StoreFlowInfo> res = pageInfo.getRecords();

        // 获取用户喜欢的流程ID列表
        Set<String> userLikes = new HashSet<>(likeMapper.getFlowIdsByUserId(condition.getUserId()));

        // 遍历查询结果，设置标签和用户喜欢状态
        for (StoreFlowInfo flow : res) {
            List<Tag> tagList = tagMapper.selectBatchIds(storeFlowTagMapper.getTagIdsByFlowId(flow.getFlowId()));
            flow.setTags(tagList);
            flow.setLikedByUser(userLikes.contains(flow.getFlowId()));
        }

        // 返回结果
        return new GetFlowsByConditionResult(true, pageInfo.getTotal(), res);
    }


    @Override
    public LikeFlowResult toggleLike(Like like) {
        Boolean liked = likeMapper.exist(like);
        if (liked) {
            likeMapper.delete(like);
        } else{
            likeMapper.insert(like);
        }
        Integer likeCount = likeMapper.getLikesCountByFlowId(like.getFlowId());
        return new LikeFlowResult(!liked, likeCount);
    }



    @Override
    public DownloadFlowResult downloadFlow(Download download) {
        if (!downloadMapper.exist(download)){
            downloadMapper.insert(download);
        }
        StoreFlow flow = storeFlowMapper.selectById(download.getFlowId());
        return DownloadFlowResult.from(flow);
    }

    @Override
    public GetTagsResult getTags() {
        List<Tag> tags = tagMapper.selectList(null);
        return new GetTagsResult(tags);
    }

    @Override
    public List<DownloadFlowResult> getAllFlows() {
        List<StoreFlow> flows =  storeFlowMapper.selectList(null);
        List<DownloadFlowResult> result = new ArrayList<>();
        for (StoreFlow flow : flows) {
            result.add(DownloadFlowResult.from(flow));
        }
        return result;
    }

    @Override
    public List<DownloadFlowResult> getChatFlows(String flowId) {


        // 获取当前用户的 ID
        String userId = UserContext.getUserId();


        LambdaQueryWrapper<UserChatFlow> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserChatFlow::getUserId, userId);

        // 使用 storeFlowMapper 查询满足条件的所有记录
        List<UserChatFlow> flowIds = userChatFlowMapper.selectList(lambdaQueryWrapper);

        List<DownloadFlowResult> result = new ArrayList<>();
        boolean find=false;
        for (UserChatFlow flow : flowIds) {

            if(flowId==null || flow.getFlowId().equals(flowId)){
                find=true;
            }
            boolean exist=false;

            LambdaQueryWrapper<ModelLangflow> modelLambdaQueryWrapper = new LambdaQueryWrapper<>();
            modelLambdaQueryWrapper.eq(ModelLangflow::getModelId, flow.getFlowId());
            ModelLangflow modelLangflow = modelLangflowMapper.selectOne(modelLambdaQueryWrapper);
            if(modelLangflow!=null && modelLangflow.getData()!=null){
                exist=true;
                result.add(DownloadFlowResult.from(modelLangflow));
            }else {
                LambdaQueryWrapper<StoreFlow> storeFlowLambdaQueryWrapper = new LambdaQueryWrapper<>();
                storeFlowLambdaQueryWrapper.eq(StoreFlow::getFlowId, flow.getFlowId());
                StoreFlow storeFlow = storeFlowMapper.selectOne(storeFlowLambdaQueryWrapper);
                if(storeFlow!=null && storeFlow.getData()!=null){
                    exist=true;
                    result.add(DownloadFlowResult.from(storeFlow));
                }
            }
            if(!exist){
                LambdaQueryWrapper<UserChatFlow> userChatFlowLambdaQueryWrapper = new LambdaQueryWrapper<>();
                userChatFlowLambdaQueryWrapper.eq(UserChatFlow::getFlowId, flow.getFlowId());
                userChatFlowMapper.delete(userChatFlowLambdaQueryWrapper);
            }

        }
        if(!find){
            boolean exist=false;

            LambdaQueryWrapper<ModelLangflow> modelLambdaQueryWrapper = new LambdaQueryWrapper<>();
            modelLambdaQueryWrapper.eq(ModelLangflow::getModelId, flowId);
            ModelLangflow modelLangflow = modelLangflowMapper.selectOne(modelLambdaQueryWrapper);
            if(modelLangflow!=null && modelLangflow.getData()!=null){
                exist=true;
                result.add(DownloadFlowResult.from(modelLangflow));
            }else {
                LambdaQueryWrapper<StoreFlow> storeFlowLambdaQueryWrapper = new LambdaQueryWrapper<>();
                storeFlowLambdaQueryWrapper.eq(StoreFlow::getFlowId, flowId);
                StoreFlow storeFlow = storeFlowMapper.selectOne(storeFlowLambdaQueryWrapper);
                if(storeFlow!=null && storeFlow.getData()!=null){
                    exist=true;
                    result.add(DownloadFlowResult.from(storeFlow));
                }
            }

            if(exist){
                // 创建雪花算法生成器实例
                SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1, 1);
                long generatedId = idGenerator.nextId();

                UserChatFlow record = new UserChatFlow();
                record.setId(generatedId);
                record.setFlowId(flowId);
                record.setUserId(userId);
                userChatFlowMapper.insert(record);
            }

        }
        return result;
    }

    @Override
    public List<Folder> selectFolderByUserId(String userId){
        List<Folder> folders = folderMapper.selectByUserId(userId);
        // 如果该用户没有文件夹，则创建一个默认的文件夹
        if (folders == null || folders.isEmpty()) {
            Folder newFolder = new Folder();
            newFolder.setUserId(userId);
            folderMapper.insert(newFolder); // 插入新文件夹
            folders = new ArrayList<>();
            folders.add(newFolder);
        }
        // 返回已存在的文件夹
        return folders;
    }
    @Override
    public List<UserApiKeys> getAllUserApiKeys(String userId){
        LambdaQueryWrapper<UserApiKeys> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserApiKeys::getUserId, userId);
        return userApiKeysMapper.selectList(queryWrapper);
    }
}
